package com.tencent.wepay.helper;
import java.io.InterruptedIOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Loader  { 
  private static Logger logger=LoggerFactory.getLogger(Loader.class);
  static final String TSTR = "Caught Exception while in Loader.getResource. This may be innocuous.";

  static private boolean java1 = true;
  
  static private boolean ignoreTCL = false;
  
  static {
    String prop = OptionConverter.getSystemProperty("java.version", null);
    
    if(prop != null) {
      int i = prop.indexOf('.');
      if(i != -1) {	
	if(prop.charAt(i+1) != '1')
	  java1 = false;
      } 
    }
    String ignoreTCLProp = OptionConverter.getSystemProperty("log4j.ignoreTCL", null);
    if(ignoreTCLProp != null) {
      ignoreTCL = OptionConverter.toBoolean(ignoreTCLProp, true);      
    }   
  }

  public static URL getResource(String resource, @SuppressWarnings("rawtypes") Class clazz) {
      return getResource(resource);
  }

  static public URL getResource(String resource) {
	  ClassLoader classLoader = null;
	  URL url = null;
    
	  try {
		  if(!java1 && !ignoreTCL) {
			  classLoader = getTCL();
			  if(classLoader != null) {
				  logger.debug("Trying to find ["+resource+"] using context classloader "+classLoader+".");
				  url = classLoader.getResource(resource);      
				  if(url != null) {
					  return url;
				  }
			  }
		  }
  	
		  classLoader = Loader.class.getClassLoader(); 
		  if(classLoader != null) {
			  logger.debug("Trying to find ["+resource+"] using "+classLoader+" class loader.");
			  url = classLoader.getResource(resource);
			  if(url != null) {
				  return url;
			  }
		  }
	  } catch(IllegalAccessException t) {
		  logger.warn(TSTR, t);
	  } catch(InvocationTargetException t) {
		  if (t.getTargetException() instanceof InterruptedException
                || t.getTargetException() instanceof InterruptedIOException) {
			  Thread.currentThread().interrupt();
		  }
		  logger.warn(TSTR, t);
	  } catch(Throwable t) {
		  logger.warn(TSTR, t);
	  }
    
      	logger.debug("Trying to find ["+resource+"] using ClassLoader.getSystemResource().");
      	return ClassLoader.getSystemResource(resource);
  	} 
  
  public static boolean isJava1() {
    return java1;
  }

  private static ClassLoader getTCL() throws IllegalAccessException, 
    InvocationTargetException {
    Method method = null;
    try {
      method = Thread.class.getMethod("getContextClassLoader", null);
    } catch (NoSuchMethodException e) {
      return null;
    }
    
    return (ClassLoader) method.invoke(Thread.currentThread(), null);
  }

  @SuppressWarnings("rawtypes")
  static public Class loadClass (String clazz) throws ClassNotFoundException {
    
    if(java1 || ignoreTCL) {
      return Class.forName(clazz);
    } else {
      try {
	    return getTCL().loadClass(clazz);
      }
     
      catch(InvocationTargetException e) {
          if (e.getTargetException() instanceof InterruptedException
                  || e.getTargetException() instanceof InterruptedIOException) {
              Thread.currentThread().interrupt();
          }
      } catch(Throwable t) {
      }
    }
    return Class.forName(clazz);
  }
}
